#-*- coding: UTF-8 -*-

from query import Query
import re

class QuestionTemplate():
    def __init__(self):
        self.q_template_dict = {
            0: self.get_instance,
            1: self.get_nc_relation,
            2: self.get_na_subclass,
            3: self.get_nc_subclass,
            4: self.get_nc_property,
            5: self.get_nc_similar,
            6: self.get_nc_successor,
            7: self.get_nc_precursor,
            8: self.get_superclass,
            9: self.get_nc_related,
            10: self.get_nc_introduction,
        }

        # 连接数据库
        self.graph = Query()
        # # 测试数据库是否连接上
        # result = self.graph.run(f"match(n:owl__Class)-[r:rdfs__subClassOf]->(m:owl__Class) where n.uri='隐私权' return m.uri")
        # print(result)
        # exit()

    # question是分词之后的问句{w.word}/{w.flag}，即（pos_quesiton），未替换成词性；template例如0\tnc 实例
    def get_question_answer(self, question, template):
        # 如果问题模板的格式不正确则结束
        assert len(str(template).strip().split("\t")) == 2
        template_id, template_str = int(str(template).strip().split("\t")[0]), str(template).strip().split("\t")[1]
        self.template_id = template_id
        self.template_str2list = str(template_str).split()

        # 预处理问题
        question_word, question_flag = [], []
        for one in question:
            word, flag = one.split("/")
            question_word.append(str(word).strip())
            question_flag.append(str(flag).strip())
        assert len(question_flag) == len(question_word)
        self.question_word = question_word
        self.question_flag = question_flag
        self.raw_question = question
        # 根据问题模板来做对应的处理，获取答案
        answer = self.q_template_dict[template_id]()
        return answer

    # 获取领域名词nc
    def get_nc_name(self):
        ## 获取nc在原问题中的下标
        tag_index = self.question_flag.index("nc")
        ## 获取nc名称
        nc_name = self.question_word[tag_index]
        return nc_name

    # 获取领域名词na
    def get_na_name(self):
        ## 获取na在原问题中的下标
        tag_index = self.question_flag.index("na")
        ## 获取na名称
        na_name = self.question_word[tag_index]
        return na_name

    def get_name(self, type_str):
        name_count = self.question_flag.count(type_str)
        if name_count == 1:
            ## 获取nm在原问题中的下标
            tag_index = self.question_flag.index(type_str)
            ## 获取电影名称
            name = self.question_word[tag_index]
            return name
        else:
            result_list = []
            for i, flag in enumerate(self.question_flag):
                if flag == str(type_str):
                    result_list.append(self.question_word[i])
            return result_list

    def get_num_x(self):
        x = re.sub(r'\D', "", "".join(self.question_word))
        return x

    # 0:nc 实例
    def get_instance(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match (m)-[k:instanceOf]->(n) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = nc_name + "的实例有" + str(answer) + "。"
        return final_answer


    # 1:nc nc关系
    def get_nc_relation(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match (m)-[k:Association]->(n) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = "与" + nc_name + "的内容有关联的有" + str(answer) + "。"
        return final_answer

    # 2:na 子类
    def get_na_subclass(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        na_name = self.get_na_name()
        cql = f"match(n:owl__Class)-[r:rdfs__subClassOf]->(m:owl__Class) where m.uri='{na_name}' return n.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = na_name + "的子类有" + str(answer) + "。"
        return final_answer

    # 3:nc 子类
    def get_nc_subclass(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class)-[r:rdfs__subClassOf]->(m:owl__Class) where m.uri='{nc_name}' return n.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = nc_name + "的子类有" + str(answer) + "。"
        return final_answer

    # 4:nc 属性
    def get_nc_property(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class) where n.uri='{nc_name}' return n.form"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = nc_name + "的属性是" + str(answer) + "。"
        return final_answer

    # 5:nc 相似内容
    def get_nc_similar(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match (m)-[k:Association]->(n) where m.uri='{nc_name}' return n.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = "与" + nc_name + "的有相似内容的是" + str(answer) + "。"
        return final_answer

    # 6:nc 后继
    def get_nc_successor(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class)-[r:precursorOf]->(m:owl__Class) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = "在了解" + nc_name + "之后可以了解" + str(answer) + "。"
        return final_answer

    # 7:nc 前驱
    def get_nc_precursor(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class)-[r:successorOf]->(m:owl__Class) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = "在了解" + nc_name + "之前需要了解" + str(answer) + "。"
        return final_answer

    # 8:nc 父类
    def get_superclass(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class)-[r:rdfs__subClassOf]->(m:owl__Class) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = nc_name + "的父类有" + str(answer) + "。"
        return final_answer

    # 9:nc 相关内容
    def get_nc_related(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match (m)-[k:Association]->(n) where m.uri='{nc_name}' return n.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = "与" + nc_name + "的有关联内容的是" + str(answer) + "。"
        return final_answer

    # 10:nc 介绍
    def get_nc_introduction(self):
        # 获取问题中的领域名词，这个是在原问题中抽取的
        nc_name = self.get_nc_name()
        cql = f"match(n:owl__Class)-[r:rdfs__subClassOf]->(m:owl__Class) where n.uri='{nc_name}' return m.uri"
        print(cql)
        answer = self.graph.run(cql)
        print(answer)
        answer_set = set(answer)
        answer_list = list(answer_set)
        answer = "、".join(answer_list)
        final_answer = nc_name + str(answer) + "。"
        return final_answer